package io.github.kimmking.gateway.outbound.netty;

import io.github.kimmking.gateway.constant.GConstant;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Promise;

import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @ClassName NettyHttpPool
 * @Description
 * @Author Jingxiao.Ye
 * @Date 2021/11/22 上午1:20
 * @Version V1.0
 * @Since JDK 11
 */
public class NettyHttpPool {


    ThreadPoolExecutor threadPoolExecutor = null;

    public NettyHttpPool() {
        this(Runtime.getRuntime().availableProcessors(),50,3000,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(200));
    }

    public NettyHttpPool(int corePoolSize,
                         int maximumPoolSize,
                         long keepAliveTime,
                         TimeUnit unit,
                         BlockingQueue<Runnable> workQueue) {
        this.threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
    }

    public Future<FullHttpResponse> get(String url, Map<String, Iterable<?>> headers,long timeout){
        NettyHttp nettyHttp = new NettyHttp(url,HttpMethod.GET,headers);
        Promise<FullHttpResponse> promise = new DefaultPromise<>(NettyHttp.eventExecutor);
        threadPoolExecutor.execute(()->{
            try {
                Future<FullHttpResponse> request = nettyHttp.request();
                FullHttpResponse response = request.get(timeout, TimeUnit.MILLISECONDS);
                promise.setSuccess(response);
            } catch (MalformedURLException | InterruptedException | ExecutionException | TimeoutException e) {
                e.printStackTrace();
                promise.setFailure(e);
            }
        });
        return promise;
    }

    public Future<FullHttpResponse> post(String url, Map<String, Iterable<?>> headers, byte[] body,long timeout){
        NettyHttp nettyHttp = new NettyHttp(url,HttpMethod.POST,headers);
        Promise<FullHttpResponse> promise = new DefaultPromise<>(NettyHttp.eventExecutor);
        threadPoolExecutor.execute(()->{
            try {
                Future<FullHttpResponse> request = nettyHttp.request();
                FullHttpResponse response = request.get(timeout, TimeUnit.MILLISECONDS);
                promise.setSuccess(response);
            } catch (MalformedURLException | InterruptedException | ExecutionException | TimeoutException e) {
                e.printStackTrace();
            }
        });
        return promise;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Future<FullHttpResponse> responseFuture1 = new NettyHttpPool().get("http://127.0.0.1:8088/api/hello", null, 3000);
        FullHttpResponse response = responseFuture1.get();
        System.out.println(new String(ByteBufUtil.getBytes(response.content())));
    }
}
